/**
 * @(#)Logger.java Mar 6, 2007
 *
 * Copyright (c) 2005-2010 Psiqueware S.A. de C.V. All Rights Reserved.
 * This software is the proprietary information Psiqueware S.A. de C.V.
 * Use is subject to license terms.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * <br/>Usuario : AngelElectrico
 * <br/>Creaci&oacute;n: Mar 6, 2007 - 1:25:53 PM
 * <br/>
 * <br/>
 * <br/><t5>Cambios :</t5>
 * <br/><b>Fecha | Autor  |  Cambios</b>
 * <ul>
 * <li>Mar 6, 2007 | <a href = "mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a> | Creaci&oacute;n del Objeto.</li>
 *
 * </ul>
 */

package com.psiqueware.alheli.logging.log4j;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.RollingFileAppender;

import java.io.IOException;

/**
 * Logger B&aacute;sico para utilizarse a manera de indirecci&oacute;n
 * de Log4j y util.Logging
 * <br/>Paquete Original: com.psiqueware.basico.logging
 * <br/>Nombre  Original: Logger
 * <br/>Oprima para ver : <a href="Logger.java.html"><i>C&oacute;digo Fuente</i> </a>
 *
 * @author <a href="mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a>
 * @version Revision: 1.1 Mar 6, 2007 1:25:53 PM
 * @noinspection ClassWithoutNoArgConstructor, ClassWithoutToString
 */
public final class Logger4j implements com.psiqueware.alheli.logging.Logger
{

    private final Logger m_logger;

    /**
     * Crea un logger para la cadena.
     *
     * @param s cadena que va a identificar nuestro logger.
     */

    public Logger4j(final String s)
    {
        m_logger = Logger.getLogger(s);
    }

    /**
     * Crea un logger para la clase.
     *
     * @param clazz cuyoo logger se quiere crear.
     */
    public Logger4j(final Class clazz)
    {
        m_logger = Logger.getLogger(clazz);
    }


    /**
     * Se utiliza para mensajes similares al modo "verbose" en otras aplicaciones.
     * Implica un alto detalle de logeo.
     *
     * @param o object a imprimir.
     */
    public void info(final Object o)
    {
        m_logger.info(Formato.formatea(o));
    }

    /**
     * Se utiliza para mensajes similares al modo "verbose" en otras aplicaciones.
     * Implica un alto detalle de logeo.
     *
     * @param o object a imprimir.
     */
    public void info(final Object o, final Throwable throwable)
    {
        m_logger.info(Formato.formatea(throwable));
        m_logger.info(Formato.formatea(o), throwable);
    }

    /**
     * Se utiliza para escribir mensajes de depuraci&oacute;n.
     * Estos eventos este m_log no debe estar activado cuando la aplicaci&oacute;n se encuentre en producci&oacute;n.
     *
     * @param o object
     */
    public void debug(final Object o)
    {
        m_logger.debug(Formato.formatea(o));
    }

    /**
     * Se utiliza para escribir mensajes de depuraci&oacute;n.
     * Estos eventos este m_log no debe estar activado cuando la aplicaci&oacute;n se encuentre en producci&oacute;n.
     *
     * @param o object
     */
    public void debug(final Object o, final Throwable throwable)
    {
        m_logger.debug(Formato.formatea(throwable));
        m_logger.debug(Formato.formatea(o), throwable);
    }

    /**
     * Se utiliza para mensajes de alerta sobre eventos que se desea mantener constancia.
     * Estos eventos no afectan el correcto funcionamiento del programa.
     * A partir de este nivel se pretende utilizar en producci&oacute;n los logs.
     *
     * @param o object
     */
    public void warn(final Object o)
    {
        m_logger.warn(Formato.formatea(o));
    }

    /**
     * Se utiliza para mensajes de alerta sobre eventos que se desea mantener constancia.
     * Estos eventos no afectan el correcto funcionamiento del programa.
     * A partir de este nivel se pretende utilizar en producci&oacute;n los logs.
     *
     * @param o object
     */
    public void warn(final Object o, final Throwable throwable)
    {
        m_logger.warn(Formato.formatea(throwable));
        m_logger.warn(Formato.formatea(o), throwable);
    }

    /**
     * Se utiliza en mensajes de error de la aplicaci&oacute;n que se desea guardar.
     * Estos eventos afectan al programa pero lo dejan seguir funcionando, como por ejemplo que alg&uacute;n par&aacute;metro de configuraci&oacute;n no es correcto y se carga el par&aacute;metro por defecto.
     *
     * @param o object
     */
    public void error(final Object o)
    {
        m_logger.error(Formato.formatea(o));
    }

    /**
     * Se utiliza en mensajes de error de la aplicaci&oacute;n que se desea guardar.
     * Estos eventos afectan al programa pero lo dejan seguir funcionando, como por ejemplo que alg&uacute;n par&aacute;metro de configuraci&oacute;n no es correcto y se carga el par&aacute;metro por defecto.
     *
     * @param o object
     */
    public void error(final Object o, final Throwable throwable)
    {
        m_logger.error(Formato.formatea(throwable));
        m_logger.error(Formato.formatea(o), throwable);
    }


    /**
     * Se utiliza para mensajes cr&iacute;ticos del sistema.
     * Generalmente luego de guardar el mensaje el programa abortar&aacute;.
     *
     * @param o a logear.
     */
    public void fatal(final Object o)
    {
        m_logger.fatal(Formato.formatea(o));
        System.exit(1);
    }

    /**
     * Se utiliza para mensajes cr&iacute;ticos del sistema.
     * Generalmente luego de guardar el mensaje el programa abortar&aacute;.
     *
     * @param o a logear.
     */
    public void fatal(final Object o, final Throwable throwable)
    {
        m_logger.fatal(Formato.formatea(throwable));
        m_logger.fatal(Formato.formatea(o), throwable);
        System.exit(1);
    }


    public boolean isDebugEnabled()
    {
        return m_logger.isDebugEnabled();
    }

    public boolean isInfoEnabled()
    {
        return m_logger.isInfoEnabled();
    }

    /**
     * Utilidades para manipular Log4j programaticamente.
     * <br/>Paquete Original: com.psiqueware.alheli.logging.log4j
     * <br/>Nombre  Original: Logger4j$Util
     * <br/><a href="Logger4j.java.html"><i>Ver C&oacute;digo Fuente</i> </a>
     *
     * @author <a href = "mailto:AngelElectrico@PsiqueWare.com">&Aacute;ngel El&eacute;ctrico</a>
     * @version Revision: 1.0
     */
    public static class Util
    {

        /**
         * Cambia el nivel de Logging.
         *
         * @param level a establecer.
         */
        public static void cambiarNivelLogging(final Level level)
        {
            final Logger root = Logger.getRootLogger();
            root.setLevel(level);
        }

        /**
         * Agrega un appender al Logger4j ra&iacute;z.
         *
         * @param name           of the appender.
         * @param strPattern     A flexible layout configurable with pattern string. This code is known to have synchronization and other issues which are not present in org.apache.log4j.EnhancedPatternLayout. EnhancedPatternLayout should be used in preference to PatternLayout.
         * @param fileName       Instantiate a RollingFileAppender and open the file designated by filename. The opened filename will become the ouput destination for this appender.
         * @param maxBackupIndex Set the maximum number of backup files to keep around.
         *                       <p/>
         *                       The MaxBackupIndex option determines how many backup files are kept before the oldest is erased.
         *                       This option takes a positive integer value. If set to zero, then there will be no backup files and the log file will be truncated when it reaches MaxFileSize.
         * @param maxFileSize    Set the maximum size that the output file is allowed to reach before being rolled over to backup files.
         *                       <p/>
         *                       In configuration files, the MaxFileSize option takes an long integer in the range 0 - 2^63. You can specify the value with the suffixes "KB", "MB" or "GB" so that the integer is interpreted being expressed respectively in kilobytes, megabytes or gigabytes. For example, the value "10KB" will be interpreted as 10240.
         */
        public static void addRollingFileAppender(final String name, final String strPattern, final String fileName, final int maxBackupIndex, final String maxFileSize)
        {
            try
            {
                final Logger root = Logger.getRootLogger();
                final RollingFileAppender appender = new RollingFileAppender(new PatternLayout(strPattern), fileName, true);
                appender.setName(name);
                appender.setMaxBackupIndex(maxBackupIndex);
                appender.setMaxFileSize(maxFileSize);
                root.addAppender(appender);
            }
            catch (IOException e)
            {
                final String error = "<error><msg>No se pudo configurar el appender.</msg><parametros>" + fileName + "</parametros></error>";
                System.err.println(error);
                System.err.println(e);
                throw new IllegalArgumentException(error, e);
            }
        }

        /**
         * Elimina un appender.
         *
         * @param name nombre del appender a eliminar.
         */
        public static void removeAppender(final String name)
        {
            final Logger root = Logger.getRootLogger();
            root.removeAppender(name);
        }

    }
}

